<?php
/**
 * 企业微信联系人应用
 * Created by PhpStorm.
 * User: zd
 * Date: 2018/10/8
 * Time: 15:52
 */

namespace app\api\service;

use app\api\model\HandoverLog;
use app\api\model\UserWorkuser;
use app\api\model\WorkDepartment;
use app\api\model\WorkdepartmentWorkuser;
use app\api\model\WorkUser;
use app\lib\enum\AuthStatusEnum;
use app\lib\exception\CardException;
use app\lib\exception\TokenException;
use \app\api\model\ThirdApp;
use app\lib\exception\UserException;
use think\Cache;
use think\Db;
use think\Exception;
use think\Loader;
use think\Request;


Loader::import('WorkWx.callback.WXBizMsgCrypt',EXTEND_PATH);
Loader::import('WorkWx.api.src.ServiceCorpAPI',EXTEND_PATH,'.class.php');

/**
 * 联系人应用service类
 * Class WorkContact
 * @package app\api\service
 */
class WorkContact
{
    private $encodingAesKey;
    private $token;
    private $corpId;
    private $suiteID;
    private $Secret;

    function __construct()
    {
        $this->encodingAesKey = config('contact.EncodingAESKey');
        $this->token = config('contact.Token');
        $this->suiteID = config('contact.SuiteID');
        $this->Secret = config('contact.Secret');
        $this->corpId = config('work.CorpID');

    }
    /**
     * 向企业微信返回通信标识
     * @return string
     */
    public function get(){
        $work = new Work($this->encodingAesKey, $this->token, $this->corpId);
        $sEchoStr =$work->get();
        return $sEchoStr;
    }

    /**
     * 处理微信返回的消息
     * @return mixed|string
     */
    public function getNotify(){
        $work = new Work($this->encodingAesKey, $this->token,$this->suiteID);
        $result = $work->getNotify();
        if (is_array($result)){
            return true;
        }else{
            return $result;
        }
    }
    /**
     * 获取预授权码
     * @return \ServiceCorpAPI
     */
    public function getPreAuthCode(){
        $work = new Work();
        $preAuthCode = $work->getPreAuthCode($this->suiteID,$this->Secret);
        return $preAuthCode;
    }

    /**
     *根据预授权码，获取永久授权码(测试)
     * @param $code
     * @return \GetPermanentCodeRsp
     */
    public function getTestPermanentCode($code){
        $work = new Work();
        $authInfo = $work->getPermanentCode($code,$this->suiteID,$this->Secret);
        return $authInfo;
    }
    /**
     *根据预授权码，获取永久授权码
     * @param $auth_code
     * @param $expires_in
     * @param $state
     * @return \GetPermanentCodeRsp
     */
    public function getPermanentCode($auth_code){
        $work = new Work();
        $authInfo = $work->getPermanentCode($auth_code,$this->suiteID,$this->Secret);
        return $authInfo;
    }

    /**
     * 设置应用配置信息
     */
    public function setAppConfig(){
        $work = new Work();
        $preAuthCode = $this->getPreAuthCode();
        $result =  $work->setAppConfig($preAuthCode,$this->suiteID,$this->Secret);
        return $result;
    }
    /**
     * 获取授权url
     * @return string
     */
    public function getAuthUrl($token){
        $work = new Work();
        $redirect_uri = urlencode('business.17jxyx.com/index/v1/contact/get_uri');
        $authUrl = $work->makeAuthUrl($this->suiteID,$this->Secret,$redirect_uri,$token);
        return $authUrl;
    }
    /**
     * 授权添加
     * @param $uid
     * @param $result
     * @param $type
     * @return $this
     */
    public function authorizeContact($uid, $result,$type){
        $type['suitID'] = $this->suiteID;
        $info = \app\api\model\Work::creatWork($uid, $result,$type);
        return $info;
    }
    /**
     * 获取部门列表
     * @param $uid
     * @return array
     */
    public function getDepartmentList($uid){
        $corp = $this->getCorp( $uid);
        $info = $corp->DepartmentList();
        foreach ($info as $k=>$v){
            $list[$k]['d_id'] =$v->id;
            $list[$k]['name'] = $v->name;
            $list[$k]['parentid'] = $v->parentid;
            $list[$k]['order'] = $v->order;
        }
        $existList = ThirdApp::getUserDepartmentInfo($uid);
        $existList =  $existList->toArray();
       if ($existList['department']==null){
           ThirdApp::addUserAllDepartment($uid,$list);
       }
        return $list;
    }

    /**
     * 添加部门
     * @param $uid
     * @param $user
     * @return null
     */
    public function addDepartment($uid,$user){
        $corp = $this->getCorp( $uid);
        $department = new \Department();
        $department->name = $user['name'];
        $department->parentid =  intval($user['parentid']);
        $department->order = 100000;
        try{
            $result = $corp->DepartmentCreate($department);
            $user['d_id'] = $result;
            $user['order'] = 100000;
            ThirdApp::addUserDepartment($uid,$user);
        }catch (\Exception $e){
            $massage = $e->getMessage();
           $arr = explode('{',$massage);
            $result = $arr;
        }
        return $result;
    }

    /**
     * 删除部门
     * @param $uid
     * @param null $d_id
     * @return array|int|void
     */
    public function deleteDepartment($uid,$d_id=null){
        if ($d_id == null){
            $result = WorkDepartment::deleteDepartment($uid,$d_id);
        }else{
            $corp = $this->getCorp( $uid);
            Db::startTrans();
            try{
                $result = $corp->DepartmentDelete(intval($d_id));
                WorkDepartment::deleteDepartment($uid,$d_id);
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                $massage = $e->getMessage();
                $arr = explode('{',$massage);
                $arr = explode(',',$arr[1]);
                $result = $arr;
            }
        }
        return $result;
    }

    /**
     * 更新部门信息
     * @param $uid
     * @param $name
     * @param $d_id
     * @return array|void
     */
    public function updateDepartment($uid,$name,$d_id){
        $info = WorkDepartment::getDepartment($uid,$d_id);
        $info = $info->toArray();
        $department = new \Department();
        $department->id=intval($d_id);
        $department->name = $name;
        $department->parentid = intval($info['parentid']);
        $department->order = intval($info['order']);
        $corp = $this->getCorp( $uid);
        $info['name'] = $name;
        $result =  $corp->DepartmentUpdate($department);
        Db::startTrans();
        try{
            WorkDepartment::updateDepartment($uid,$d_id,$info);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            $massage = $e->getMessage();
            $arr = explode('{',$massage);
            $arr = explode(',',$arr[1]);
            $result = $arr;
        }
        return $result;
    }
    /**
     * 获取部门成员
     * @param $uid
     * @param $d_id
     * @param null $userId
    * @return false|\PDOStatement|string|\think\Collection
     */
    public function getMemberList($uid,$d_id=null){
        $corp = $this->getCorp($uid);
        if ($d_id == null){
            $result =  WorkUser::getUserList($uid);
            if ($result->isEmpty()){//第一次登录
                $info = $corp->UserList(1,1);
                  foreach ($info as $k=>$v){
                      $list[$k]['user_id'] =$v->userid;
                      $list[$k]['name'] = $v->name;
                      $list[$k]['phone'] = $v->mobile;
                      $list[$k]['d_id'] = $v->department;
                      $list[$k]['position'] = $v->position;
                  }
                WorkUser::createAllUser($uid,$list);//请求全部成员
            }
        }else{
            $department = WorkDepartment::getDepartment($uid,$d_id);
            $department =$department->toArray();
            $department_id = $department['id'];
            $result =  WorkUser::getDepartmentUser($uid,$department_id);//请求部门成员
        }
        return $result;
    }
    /**
     * 获取人员详情信息$
     * @param $uid
     * @param $userId
     * @return false|\PDOStatement|string|\think\Collection
     */
    public function getUserById($uid,$userId){
        $result =  WorkUser::getUserByID($uid,$userId);//请求部门成员
        return $result;
    }

    /**
     * 同步信息
     * @param $uid
     * @return int
     */
    public function syncUser($uid){
        $corp = $this->getCorp( $uid);
        $info = $corp->DepartmentList();
        foreach ($info as $k=>$v){
            $data[$k]['t_id'] = $uid;
            $data[$k]['d_id'] =$v->id;
            $data[$k]['name'] = $v->name;
            $data[$k]['parentid'] = $v->parentid;
            $data[$k]['order'] = $v->order;
        }
        $result = WorkDepartment::batchUpdate($data);
        return $result;
    }

    /**
     * 创建成员
     * @param $uid
     * @param $member
     * @return array|void
     */
    public function addMember($uid,array $member){
        $user = new \User();
        $user->name  = $member['name'];
        if (!isset($member['userId'])){
            $user->userid = $this->creatNum();
            $member['userId'] = $this->creatNum();
        }else{
            $user->userid = $member['userId'];
        }
        $user->department = $member['d_id'];
        $user->mobile = $member['bind_phone'];
        $user->position = $member['position'];
        $user->gender = $member['gender'];
        $leader = [];
        if (empty($member['isleader'])){
            foreach ($member['d_id'] as $key=>$value){
                $member['isleader'] [ $key] = '0';
            }
        }else{
            foreach ($member['d_id'] as $key=>$value){
                $leader['isleader'][$key] = in_array($value,$member['isleader'])?'1':'0';
            }
            $member['isleader'] =  $leader['isleader'];
        }
        $user->is_leader_in_dept = $member['isleader'];
        $corp = $this->getCorp($uid);
        try{
            $result =  $corp->UserCreate($user);
            WorkUser::createUser($uid,$member);
        }catch (\Exception $e){
            $massage = $e->getMessage();
            $arr = explode('{',$massage);
            $result = $arr;
        }
        return $result;
    }
    /**
     * 更新成员
     * @param $uid
     * @param $member
     * @return array|void
     */
    public function updateMember($uid,$member){
        $user = new \User();
        $user->name  = $member['name'];
        if (!isset($member['userId'])){
            $user->userid = $this->creatNum();
            $member['userId'] = $this->creatNum();
        }else{
            $user->userid = $member['userId'];
        }
        $user->department = $member['d_id'];
        $user->mobile = $member['bind_phone'];
        $user->position = $member['position'];
        $user->gender = $member['gender'];
        $leader = [];
        if (empty($member['isleader'])){
            foreach ($member['d_id'] as $key=>$value){
                $member['isleader'][ $key] = '0';
            }
        }else{
            foreach ($member['d_id'] as $key=>$value){
                $leader['isleader'][$key] = in_array($value,$member['isleader'])?'1':'0';
            }
            $member['isleader'] =  $leader['isleader'];
        }
        $user->is_leader_in_dept = $member['isleader'];
        $corp = $this->getCorp($uid);
        Db::startTrans();
        try{
            $result =  $corp->UserUpdate($user);
            WorkUser::updateUser($uid,$member);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            $massage = $e->getMessage();
            $arr = explode('{',$massage);
            $result = $arr;
        }
        return $result;
    }
    /**
     * 更新用户部门信息
     * @param $uid
     * @param $userInfo
     * @param $d_ids
     * @return array|void
     */
    public function updateUserDepartment($uid,$userInfo,$d_ids){
        $user = new \User();
        $user->name  = $userInfo->name;
        $user->userid = $userInfo->user_id;
        $user->department = $d_ids;
        $user->mobile = $userInfo->bind_phone;
        $user->position = $userInfo->position;
        $corp = $this->getCorp($uid);
        $userInfo = $userInfo->toArray();
        $userInfo['d_id'] = $d_ids;
        Db::startTrans();
        try{
            $result =  $corp->UserUpdate($user);
            WorkUser::updateUser($uid,$userInfo);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            $massage = $e->getMessage();
            $arr = explode('{',$massage);
            $result = $arr;
        }
        return $result;
    }
    /**
     * 删除成员
     * @param $uid 管理员id
     * @param $userId 工号
     * @return array|void
     */
    public function deleteMember($uid,$userId){
        $result =  $this->getUserNum($uid,$userId);
        if (empty($result)){
            $corp = $this->getCorp( $uid);
            Db::startTrans();
            try{
                if (count($userId) == 1){
                    $result = $corp->UserDelete($userId[0]);//单个删除
                }else{
                    $result = $corp->UserBatchDelete($userId);
                }
                WorkUser::deleteUser($uid,$userId);
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                $massage = $e->getMessage();
                $arr = explode('{',$massage);
                $result = $arr;
            }
        }
        return $result;
    }

    /**
     * 获取
     * @param $uid
     * @param $userId
     * @return array
     */
    private function getUserNum($uid,$userId){
        $info= [];
        $data =  WorkUser::getNumById($uid,$userId);
        foreach ($data as $key=>$value){
            if ($value->users_count != 0){
                $info[$key] = $value->toArray();
            }
        }
        return $info;
    }

    /**
     * 名片授权
     * @param $t_id
     * @param $type
     * @param $info
     * @param $wu_id
     * @return WorkUser
     * @throws UserException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function memberAuthorize($t_id,$type,$info,$wu_id){
        //检查名片是否已达到开通上线
        $res = ThirdApp::getApplyUser($t_id);
        if ($type == 'on' && $info == 'ai'){
            if ($res->card_num <= $res->workuser_count ){
                throw new UserException([
                    'code'=>200,
                    'msg'=>'CRM名片数量已达上限，请联系客服',
                    'error_code'=>43011
                ]);
            }
        }else if($type == 'on' && $info == 'boss'){
            if ($res->card_num <= $res->worklist_count ){
                throw new UserException([
                    'code'=>200,
                    'msg'=>'人事数量已达上限，请联系客服',
                    'error_code'=>43011
                ]);
            }
        }
        $data = $this->authorizeLogic($type, $info, $data='');
        $result =  WorkUser::authorize($data,$wu_id);
        return $result;
    }

    /**
     * 授权状态查询
     * @param $t_id
     * @return array
     */
    public function authorizeStatus($t_id){
        $result = WorkUser::authorizeStatus($t_id);
        return $result;
    }

    /**
     * 用户批量授权
     * @param $type
     * @param $info
     * @param $list
     * @return $this
     */
    public function batchMemberAuthorize($type,$info,$list){
        $data = $this->authorizeLogic($type, $info, $data='');
        $result =  WorkUser::batchAuthorize($data,$list);
        return $result;
    }

    /**
     * 工作交接
     * @param $beforeId
     * @param $endId
     * @return $this
     */
    public function handoverUser($beforeId,$endId,$num){
        $ids=[];
        $ends =[];
        //获取需要交接的用户
        $beforeUser = UserWorkuser::getIDByWid($beforeId);
        foreach ($beforeUser as $value){
            $ids[] = $value->user_id;
        }
        //获取交接的用户
        $endUser = UserWorkuser::getIDByWid($endId);
        if (!$endUser->isEmpty()){
            foreach ($endUser as $value){
                $ends[] = $value->user_id;
            }
        }
        //获取差集
        $delResult = array_intersect($ids,$ends);//删除的关系
        $addResult = array_diff($ids,$delResult);//添加的关系
        Db::startTrans();
        try{
            $logInfo['num'] = $num;
            $logInfo['wu_id'] = $endId;
            $log = HandoverLog::addLog($logInfo);
            $data['wu_id'] = $endId;
            $data['handover_id'] = $log->id;
            if (!empty($addResult)){
                UserWorkuser::batchUpdateUser($addResult,$beforeId,$data);//要添加的关系
            }
            if (!empty($delResult)){
                UserWorkuser::deleteUser($delResult,$beforeId);//要删除的关系
                //关闭名片权限
            }
            $info['ai_power']='off';
            $info['boss_power'] = 'off';
            WorkUser::updateUserInfo($beforeId,$info);
            Db::commit();
            return true;
        }catch (Exception $exception){
            Db::rollback();
           return false;
        }
    }

    /**
     * 获取客户总数量
     * @param $id 名片id
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function getCustomerNum($id,$type){
        $workuser =  WorkUser::getUserByWuID($id);
        if ($type =='handover'){
            if ($workuser->ai_power == 'on'){
                $workuser =  $workuser->visible(['id','name','ai_power','boss_power']);
                return $workuser->toArray();
            }
        }elseif ($type =='receiver'){
            if ($workuser->ai_power == 'off'){
                $workuser =  $workuser->visible(['id','name','ai_power','boss_power']);
                return $workuser->toArray();
            }
        }
        $result = UserWorkuser::getUserCount($id);
        return $result;
    }

    /**
     * 获取交接结果统计数量
     * @param $handoverId
     * @param $receiverId
     * @return array
     */
    public function getCustomerResult($handoverId,$receiverId){
        //获取需要交接的用户
        $beforeUser = UserWorkuser::getIDByWid($handoverId);
        $ids = $beforeUser->column('user_id');
        $num = $beforeUser->count();
        //获取交接的用户
        $endUser = UserWorkuser::getIDByWid($receiverId);
        $ends = $endUser->column('user_id');
        //获取交集
        $delResult = array_intersect($ids,$ends);//删除的关系
        $coincide = count($delResult);
        $result = $num-$coincide;
        return array('num'=>$num,'coincide'=>$coincide,'result'=>$result);
    }

    /**
     * 刷新access_token,并返回对象
     * @param $uid
     * @return \CorpAPI
     */
    private function getCorp($uid){
        $accessToken = new WorkAccessToken($uid);
        $authInfo = ThirdApp::getUserAuthInfo($uid);
        $key =  $authInfo->work->corpid;
        $permanent_code = $authInfo->work->permanent_code;
        $corp = $accessToken->getContactAccessToken( $this->suiteID,$this->Secret,$key,$permanent_code);
        return $corp;
    }
    /**
     * 数据集转换为树形结构
     * @param $list
     * @param $pid
     * @return array
     */
    public function  getTreeList($list,$pid){
        $tree = array();
        foreach ($list as $k=>$v ){
            if ($v['parentid'] == $pid){
               $v['son'] = $this->getTreeList($list,$v['d_id']);
               if ($v['son'] == null){
                unset($v['son']);
               }
               $tree[] = $v;
            }
        }
        return $tree;
    }
    /**
     * 默认生成工号
     * @return string
     */
    private function creatNum(){
        $randChars = getRandChar(32);
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        $salt = config('secure.token_salt');
        return md5($randChars . $timestamp . $salt);
    }

    /**
     * 授权逻辑
     * @param $type
     * @param $info
     * @param $data
     * @return mixed
     */
    private function authorizeLogic($type, $info, $data)
    {
        if ($type == 'on') {
            if ($info == 'boss') {
                $data['boss_power'] = AuthStatusEnum::ON;
            }
            $data['ai_power'] = AuthStatusEnum::ON;
        } elseif ($type == 'off') {
            if ($info == 'ai') {
                $data['ai_power'] = AuthStatusEnum::OFF;
            }
            $data['boss_power'] = AuthStatusEnum::OFF;
        }
        return $data;
    }
}